﻿//图片读取、通道处理、颜色空间转换
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

//图片操作：图片读取、通道分割与合并、颜色空间转换
void opsImage(string addr) {
    cv::Mat dstimg;
    cv::Mat srcimg = cv::imread(addr);
    //判断读取图片是否成功
    if (srcimg.empty()) {
        std::cout << "Failed to read image!" << endl;
        return;
    }

    cv::Mat pics[3];
    //分割图片的三个通道
    cv::split(srcimg, pics);
    //显示蓝色通道
    cv::imshow("b", pics[0]);
    //显示绿色通道
    cv::imshow("g", pics[1]);
    //显示红色通道
    cv::imshow("r", pics[2]);

    //存储通道向量
    std::vector<Mat> chanels;
    cv::split(srcimg, chanels);
    cv::Mat mergeimg;
    //合并通道
    cv::merge(chanels, mergeimg);
    cv::imshow("Merge Image!", mergeimg);

    //灰度转换
    cv::cvtColor(srcimg, dstimg, COLOR_BGR2GRAY);
    cv::imshow("showimage", dstimg);
}

//绿幕抠图操作
void convGreen(string addr,string addrBack) {
    cv::Mat srcImage = cv::imread(addr);
    //将原图转化为HSV色彩空间
    cv::Mat hsvImage;
    cv::cvtColor(srcImage, hsvImage, cv::COLOR_BGR2HSV);
    //使用inRange函数将图片前景抠出
    cv::Mat mask;
    cv::Scalar lowerGreen = cv::Scalar(35, 50, 50);//绿色在HSV空间中的下界值
    cv::Scalar higherGreen = cv::Scalar(85, 255, 255);//绿色在HSV空间中的上界值
    cv::inRange(hsvImage, lowerGreen, higherGreen, mask);
    cv::imshow("HSV Image", hsvImage);
    //像素赋值达到背景替换效果
    cv::Mat background = cv::imread(addrBack);
    cv::Mat result;
    srcImage.copyTo(result, mask);
    background.copyTo(result, ~mask);
    cv::imshow("Result Image", result);
    return;
}

//视频操作：读取视频
static void readVideo(string addr) {
    //定义视频帧
    cv::Mat frame;
    cv::VideoCapture cap(addr);
    if (!cap.isOpened()) {
        std::cout << "无法打开视频文件" << endl;
        return;
    }
    while (cap.read(frame) != NAN) {
        cv::imshow("Video frame",frame);
        //判断是否按下ESC，按下ESC键退出显示
        if (cv::waitKey(30) == 27) {
            break;
        }
    }
}

int main()
{
    //调用图片操作函数
    string addrStr_P="C:/Users/sun/code/DPI/img/home.jpg";
    opsImage(addrStr_P);

    //调用绿幕抠图函数
    string addrStr_Pgreen = "C:/Users/sun/code/DPI/img/home.jpg";
    string addrStr_Pbackground = "C://Users/sun/code/DPI/img/background_1.jpg";
    convGreen(addrStr_Pgreen,addrStr_P);

    //调用读取视频函数
    string addrStr_V = "C:/Users/sun/Desktop/机器学习_雷明/二维码视频/第八章/第8章-LDA的推导1.mp4";
    readVideo(addrStr_V);

    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}
